use crate::common::constants::ErrorCode;
use crate::traits::storage_io::StorageIo;
use crate::traits::storage_io::StorageType;
use crate::log_e;

#[allow(unused_extern_crates)]
extern crate std;
use std::fs;
use std::path::Path;


pub struct DefaultStorageIo;

impl From<std::io::Error> for ErrorCode {
    fn from(err: std::io::Error) -> Self {
        log_e!("file operate fail, {}", err);
        return ErrorCode::GeneralError;
    }
}

impl DefaultStorageIo {
    pub fn new() -> Self {
        Self
    }
}

impl StorageIo for DefaultStorageIo {
    fn exists(&self, storage_type: StorageType, file_name: &str) -> Result<bool, ErrorCode> {
        if storage_type != StorageType::Default {
            return Err(ErrorCode::GeneralError);
        }

        return Ok(Path::new(file_name).exists());
    }

    fn read(&self, storage_type: StorageType, file_name: &str) -> Result<crate::Vec<u8>, ErrorCode> {
        if storage_type != StorageType::Default {
            return Err(ErrorCode::GeneralError);
        }

        let context: crate::Vec<u8> = fs::read(file_name)?;
        Ok(context)
    }

    fn write(&self, storage_type: StorageType, file_name: &str, data: &[u8]) -> Result<(), ErrorCode> {
        if storage_type != StorageType::Default {
            return Err(ErrorCode::GeneralError);
        }

        fs::write(file_name, data)?;
        Ok(())
    }

    fn delete(&self, _storage_type: StorageType, _file_name: &str) -> Result<(), ErrorCode> {
        return Err(ErrorCode::GeneralError);
    }
}
